﻿using System;
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.HttpOverrides;
using Microsoft.AspNetCore.Server.Kestrel.Core;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Serialization;
using T.ServiceFramework.Spi;
using T.SF.Console.HttpHost;
using T.ServiceComponent.Error;
using T.ServiceComponent.Kernel.Service;
using HttpContext = T.ServiceComponent.Kernel.Service.HttpContext;

namespace T.SF.Console
{
    public class HostStartup
    {
        public HostStartup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        public void ConfigureServices(IServiceCollection services)
        {
            // HTTP 上下文访问器
            services.AddHttpContextAccessor();

            // 分布式缓存 + Session
            services.AddDistributedMemoryCache();
            services.AddSession(options =>
            {
                options.IdleTimeout = TimeSpan.FromMinutes(30);
                options.Cookie.HttpOnly = true;
                options.Cookie.IsEssential = true;
            });

            // 只注册 Controllers 并配置 Newtonsoft.Json
            services
                .AddControllers()
                .AddNewtonsoftJson(o =>
                {
                    o.SerializerSettings.ContractResolver = new DefaultContractResolver
                    {
                        IgnoreSerializableAttribute = true
                    };
                    o.SerializerSettings.DateFormatHandling = DateFormatHandling.MicrosoftDateFormat;
                    o.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
                    o.SerializerSettings.DateFormatString = "yyyy-MM-dd HH:mm:ss";
                });

            // 反向代理头支持
            services.Configure<ForwardedHeadersOptions>(opts =>
            {
                opts.ForwardedHeaders = ForwardedHeaders.XForwardedFor
                                      | ForwardedHeaders.XForwardedProto;
            });

            // 最大请求体大小（配置或默认 512MB）
            var maxRequestBodySize = Configuration
                .GetValue<long?>("HttpMaxRequestBodySize")
                ?? 536_870_912;

            // Kestrel 配置
            services.Configure<KestrelServerOptions>(opts =>
            {
                opts.AllowSynchronousIO = true;
                opts.Limits.MaxRequestBodySize = maxRequestBodySize;
            });

            // 表单上传限制
            services.Configure<FormOptions>(opts =>
            {
                opts.ValueLengthLimit = int.MaxValue;
                opts.MultipartBodyLengthLimit = maxRequestBodySize;
            });
        }

        public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
        {
            // 开发/生产环境区分
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }

            // 处理转发头
            app.UseForwardedHeaders();

            // 静态文件
            app.UseStaticFiles();

            // 全局异常处理
            app.UseExceptionHandler(errorApp =>
            {
                errorApp.Run(async context =>
                {
                    context.Response.StatusCode = 500;
                    context.Response.ContentType = "application/json; charset=utf-8";

                    var feature = context.Features.Get<IExceptionHandlerPathFeature>();
                    var ex = feature?.Error;

                    // 日志上报
                    TSFLogger.ExceptionLogAndReport(ex, SFContext.Host.ID);

                    // 构建返回的异常信息
                    var info = new ExceptionInfo
                    {
                        ErrorInfo = ex?.Message ?? string.Empty,
                        ErrorCode = ex is TException tex ? tex.Code : "0",
                        ErrorReason = ex is TException ? null : ex?.StackTrace
                    };

                    var sb = new StringBuilder();
                    while (ex?.InnerException != null)
                    {
                        ex = ex.InnerException;
                        sb.AppendLine("Inner ErrorInfo:" + ex.Message);
                        sb.AppendLine("Inner ErrorReason:" + ex.StackTrace);
                    }
                    info.InnerInfo = sb.ToString();

                    await context.Response.WriteAsync(JsonConvert.SerializeObject(info));
                });
            });

            // 自定义中间件 (跨域、业务等等)
            app.UseMiddlewares();

            // 路由与 Session
            app.UseRouting();
            app.UseSession();

            // 映射 Controller 路由
            app.UseEndpoints(endpoints =>
            {
                // 默认 API 路由
                endpoints.MapControllerRoute(
                    name: "DefaultApi",
                    pattern: "api/{controller=Invoke}");

                // 可选多段自定义路由
                if (AppConfig.IsEnableCustomRouter())
                {
                    endpoints.MapControllerRoute(
                        name: "CustomApi",
                        pattern: "{seg1?}/{seg2?}/{seg3?}/{seg4?}/{seg5?}/{seg6?}/{seg7?}/{seg8?}/{seg9?}/{seg10?}/{seg11?}/{seg12?}/{seg13?}/{seg14?}/{seg15?}",
                        defaults: new { controller = "Common", action = "Execute" });
                }
            });

            // 全局 HttpContext 注册
            var httpCtx = app.ApplicationServices.GetRequiredService<Microsoft.AspNetCore.Http.IHttpContextAccessor>();
            HttpContext.Configure(httpCtx);
        }
    }
}
